package com.sunwayworld.basemodule.coredata.test.service.impl;

import com.sunwayworld.basemodule.coredata.test.bean.*;
import com.sunwayworld.basemodule.coredata.test.dao.LimsTestDao;
import com.sunwayworld.basemodule.coredata.test.service.*;
import com.sunwayworld.basemodule.common.utils.GikamFormulaHelperUtils;
import com.sunwayworld.framework.at.annotation.AuditTrailEntry;
import com.sunwayworld.framework.at.annotation.AuditTrailType;
import com.sunwayworld.framework.context.ApplicationContextHelper;
import com.sunwayworld.framework.exception.checked.CheckedException;
import com.sunwayworld.framework.mybatis.mapper.MatchPattern;
import com.sunwayworld.framework.mybatis.mapper.SearchFilter;
import com.sunwayworld.framework.restful.data.RestJsonWrapperBean;
import com.sunwayworld.framework.script.BshExecutor;
import com.sunwayworld.framework.spring.annotation.GikamBean;
import com.sunwayworld.framework.utils.CollectionUtils;
import com.sunwayworld.framework.utils.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Repository
@GikamBean
public class LimsTestServiceImpl implements LimsTestService {

    @Autowired
    private LimsTestDao limsTestDao;

    @Autowired
    @Lazy
    private LimsTestMethodService methodService;

    @Autowired
    @Lazy
    private LimsTestMethodAnalyteService analyteService;

    @Autowired
    @Lazy
    private LimsTestMethodEquipmentService equipmentService;

    @Autowired
    @Lazy
    private LimsTestMethodMaterialService materialService;

    @Override
    @SuppressWarnings("unchecked")
    public LimsTestDao getDao() {
        return limsTestDao;
    }

    @Override
    @Transactional
    @AuditTrailEntry(AuditTrailType.INSERT)
    public Long insert(RestJsonWrapperBean jsonWrapper) {
        LimsTestBean limsTest = jsonWrapper.parseUnique(LimsTestBean.class);
        limsTest.setId(ApplicationContextHelper.getNextIdentity());
        getDao().insert(limsTest);
        return limsTest.getId();
    }

    @Override
    @Transactional
    public void delete(RestJsonWrapperBean wrapper) {
        List<LimsTestBean> parse = wrapper.parse(LimsTestBean.class);
        if(CollectionUtils.isEmpty(parse)) return;
        // 级联删除模板工序 和 模板工序方法
        List<Long> testIds = parse.stream().map(LimsTestBean::getId).collect(Collectors.toList());
        List<LimsTestMethodBean> methodBeans = methodService.selectListByFilter(SearchFilter.instance()
                .match("testId", testIds).filter(MatchPattern.OR));
        if(!CollectionUtils.isEmpty(methodBeans)){
            List<LimsTestMethodAnalyteBean> analyteBeans = new ArrayList<>();
            List<LimsTestMethodEquipmentBean> equipmentBeans = new ArrayList<>();
            List<LimsTestMethodMaterialBean> materialBeans = new ArrayList<>();
            methodBeans.forEach(e -> {
                LimsTestMethodAnalyteBean testBean = new LimsTestMethodAnalyteBean();
                testBean.setTestMethodId(e.getId());
                analyteBeans.add(testBean);
                LimsTestMethodMaterialBean methodBean = new LimsTestMethodMaterialBean();
                methodBean.setTestMethodId(e.getId());
                materialBeans.add(methodBean);
                LimsTestMethodEquipmentBean equipmentBean = new LimsTestMethodEquipmentBean();
                equipmentBean.setTestMethodId(e.getId());
                equipmentBeans.add(equipmentBean);
            });
            analyteService.getDao().deleteBy(analyteBeans, "testMethodId");
            equipmentService.getDao().deleteBy(equipmentBeans, "testMethodId");
            materialService.getDao().deleteBy(materialBeans, "testMethodId");
            methodService.getDao().deleteBy(methodBeans);
        }
        getDao().deleteBy(parse);
    }

    @Override
    public String testItemScript(RestJsonWrapperBean wrapper) {
        List<ScriptSelectorDTO> selectorDTOList = wrapper.parse(ScriptSelectorDTO.class);

        String script = wrapper.getParamValue("script");

        for (ScriptSelectorDTO selectorDTO : selectorDTOList) {
            script = script.replace(selectorDTO.getSelector(), selectorDTO.getValue() + "");
        }

        script = GikamFormulaHelperUtils.getRevisedScript(script);

        BshExecutor bsh = BshExecutor.instance();

        bsh.eval("import static com.sunwayworld.basemodule.common.utils.GeneralFormulaRepository.*;");
        bsh.eval("import java.text.*;");
        try {
            Object resultValue = bsh.eval(script);

            if (!ObjectUtils.isEmpty(resultValue)) {
                return ObjectUtils.toString(resultValue);
            }
        } catch (Exception e) {
            throw new CheckedException("CORE.MODULE.SCRIPT.TESTS.TIP.SCRIPT_ERROR");
        }

        return null;
    }
}
